<?php

namespace app\index\service\wechatprocess;

use app\common\model\oms\MemberScanBind as MemberScanBindModel;
use app\common\model\jooj_member\ViewMemberIndex as ViewMemberIndexModel;
use app\common\model\jooj_member\MemberIndex as MemberIndexModel;
use app\common\model\jooj_member\MemberIndexInfo as MemberIndexInfoModel;
use app\common\model\oms\StaffStore as StaffStoreModel;
use app\common\model\jsm\Members as MembersModel;
use app\common\model\oms\MemberSign as MemberSignModel;
use app\index\service\StaffService;
use app\common\service\MemberGetwayService;
use app\common\service\arvato\ArvatoMemberService;
use app\common\arvato\CommonPush;
use app\common\model\oms\Store as StoreModel;

/**
 * 微信扫码service
 */
class WechatScanProcessorService extends BaseProcessorService {

    private $_qrscene = null;
    private $_openid = null;
    private $_appid = null;
    private $_companyId = null;
    private $_mpId = null;
    private $_vipId = 0;
    //Model对象的全局变量
    private $_memberScanBindModel = null;
    private $_viewMemberIndexModel = null;
    private $_memberIndexModel = null;
    private $_membersModel = null;
    private $_memberIndexInfoModel = null;
    private $_memberSignModel = null;

    /**
     * 构造函数
     * @param type $mps
     * @param type $message
     */
    public function __construct($mps, $message) {

        $xml = $message['XmlArr'];

        $this->_qrscene = str_replace('qrscene_', '', $xml['EventKey']);
        $this->_openid = $message['openid'];
        $this->_appid = $message['app_id'];
        $this->_companyId = $mps['o_id'];
        $this->_mpId = $mps['mp_id'];
    }

    /**
     * 处理扫码的业务逻辑
     * @return type
     */
    public function DealScan() {

        switch (true) {
            case (is_numeric($this->_qrscene) && $this->_qrscene > self::TEMP_SCAN_NUMBER):
                //临时二维码业务处理
                $this->_memberScanBindModel = new MemberScanBindModel($this->_companyId);
                $this->_viewMemberIndexModel = new ViewMemberIndexModel($this->_companyId);
                $this->_memberIndexModel = new MemberIndexModel($this->_companyId);
                $this->_memberIndexInfoModel = new MemberIndexInfoModel($this->_companyId);
                return $this->_tempScan();

            case (stristr($this->_qrscene, 'staff_')):

                $this->_viewMemberIndexModel = new ViewMemberIndexModel($this->_companyId);
                $this->_membersModel = new MembersModel($this->_mpId);
                $this->_memberIndexModel = new MemberIndexModel($this->_companyId);
                $this->_memberIndexInfoModel = new MemberIndexInfoModel($this->_companyId);
                $this->_memberSignModel = new MemberSignModel($this->_companyId);

                //以staff_开始的永久职员二维码
                $staffId = str_replace('staff_', '', $this->_qrscene);
                return $this->_staffScan($staffId);

            case (stristr($this->_qrscene, 'store_')):

                $this->_viewMemberIndexModel = new ViewMemberIndexModel($this->_companyId);
                $this->_membersModel = new MembersModel($this->_mpId);
                $this->_memberIndexModel = new MemberIndexModel($this->_companyId);
                $this->_memberIndexInfoModel = new MemberIndexInfoModel($this->_companyId);
                $this->_memberSignModel = new MemberSignModel($this->_companyId);

                //以store_开始的永久门店二维码
                $storeId = str_replace('store_', '', $this->_qrscene);
                return $this->_storeScan($storeId);
        }

        return ["msg" => "I don't know what you want me to do!"];
    }

    /**
     * 扫临码
     */
    private function _tempScan() {

        $this->_viewMemberIndexModel->startTrans();
        //获得真实的扫码场景ID
        $usbId = $this->_qrscene - self::TEMP_SCAN_NUMBER;

        $memberScanBind = $this->_memberScanBindModel->getMemberScanBindByUsbId($usbId);
        //判断临码表的值是否符合要求（不符合要求直接返回）
        $memberScanBindIsTrue = $this->_memberBindScanIsTrue($memberScanBind, $usbId);
        if ($memberScanBindIsTrue !== true) {
            return $memberScanBindIsTrue;
        }

        $scan_member_code = $memberScanBind['member_code'];
        //检查码值对应的member_code
        $scanViewMemberIndex = $this->_viewMemberIndexModel->getViewMemberIndexByCondition(['member_code' => $scan_member_code]);
        if (!$scanViewMemberIndex) {

            $updateData = [
                'status' => 40,
                'message' => '会粉表中不存在此用户，member_code=' . $memberScanBind['member_code']
            ];
            $this->_memberScanBindModel->updateScanInfo(['usb_id' => $usbId], $updateData);
            return ['msg' => "temp scan [this member_code don't find in memberIndexView]"];
        }

        if ($scanViewMemberIndex['account_code']) {
            $updateData = [
                'status' => 40,
                'message' => '此微信号已绑定别的账户，不可再绑定'
            ];
            $this->_memberScanBindModel->updateScanInfo(['usb_id' => $usbId], $updateData);
            return ['msg' => "temp scan [this scan viewMemberIndex have account_code]member_code={$memberScanBind['member_code']}"];
        }

        //根据openid查询会粉表
        $openIdViewMemberIndex = $this->_viewMemberIndexModel->getViewMemberIndexByCondition(['account_code' => $this->_openid]);

        if ($openIdViewMemberIndex['mobile_status'] == 1) {
            //该openid已绑定过其它会员，则结束
            $updateData = [
                'status' => 40,
                'message' => '此微信号已绑定别的账户，不可再绑定'];
            $this->_memberScanBindModel->updateScanInfo(['usb_id' => $usbId], $updateData);
            return ['msg' => "temp scan [this openid already is vip]"];
        }

        if (empty($openIdViewMemberIndex)) {
            //把openId直接绑定到memberCode上即可
            $result = $this->_memberIndexModel->bindMemberIndex("openId", 0, $this->_openid, $scan_member_code, 0);

            if (!$result) {
                $updateData = [
                    'status' => 40,
                    'message' => '会员信息更新失败'];
                $this->_memberScanBindModel->updateScanInfo(['usb_id' => $usbId], $updateData);
                return ['msg' => 'temp scan [memberIndex update fail]'];
            }
            $memberCodeArr = [$scan_member_code];
        } else {
            //发现两条记录都有，这时候还是依然以微信的为主
            $uniId_openId = $openIdViewMemberIndex['jj_uni_id'];
            $memberCodeArr = $this->_memberIndexModel->bindMemberIndex("mutil", 0, 0, $scan_member_code, $uniId_openId);
            if (empty($memberCodeArr)) {
                if (!$result) {
                    $updateData = [
                        'status' => 40,
                        'message' => '会员信息更新失败'];
                    $this->_memberScanBindModel->updateScanInfo(['usb_id' => $usbId], $updateData);
                    return ['msg' => 'temp scan [memberIndex update fail]'];
                }
            }
            //清理了memberIndexInfo中
            $this->_memberIndexInfoModel->clearBindData($memberCodeArr);
        }

        $updateData = [
            'service_p' => $memberScanBind['staff_id'],
            'service_store' => $memberScanBind['store_id'],
            'service_qrscene' => $this->_qrscene
        ];
        //更新最后的验光相关信息
        $memberGetwayService = new MemberGetwayService();
        $memberGetwayService->updateViewField($this->_companyId, $updateData, $memberCodeArr, $this->_openid);

        $updateData = [
            'status' => 20,
            'message' => '绑定信息成功'];
        $this->_memberScanBindModel->updateScanInfo(['usb_id' => $usbId], $updateData);

        $this->_viewMemberIndexModel->commit();

        if ($this->_appid == 'wx68f2b24a06465298') {
            try {
                $ArvatoMemberService = new ArvatoMemberService();

                //推送arvato
                $openIdViewMemberIndex = $this->_viewMemberIndexModel->getViewMemberIndexByCondition(['account_code' => $this->_openid]);
                if ($openIdViewMemberIndex) {
                    $data = $ArvatoMemberService->getCompleteInfo(['jj_uni_id' => $openIdViewMemberIndex['jj_uni_id']]);

                    $data['birthday'] = 0 != (int) $data['birthday'] ? $data['birthday'] : '';

                    $commonPush = new CommonPush();
                    $commonPush->pushToRedis($data, 'bindOpenid');
                }
            } catch (\Exception $ex) {
                $updateData = [
                    'status' => 20,
                    'message' => '绑定成功:' . $ex->getMessage()];
                $this->_memberScanBindModel->updateScanInfo(['usb_id' => $usbId], $updateData);
            }

        }
        return true;
    }

    /**
     * 扫职员码
     * @param type $staffId
     */
    private function _staffScan($staffId) {
        $staffStoreModel = new StaffStoreModel();
        $staffStore = $staffStoreModel->getStaffStoreByCondition([
            'staff_id' => $staffId,
            'is_current' => 1
        ]);
        $storeId = isset($staffStore['store_id']) ? $staffStore['store_id'] : 0;
        $memberCode = $this->_registerMember($staffId, $storeId, self::COME_FROM_STAFF);

        if (isset($memberCode['msg']) && !empty($memberCode['msg'])) {
            return $memberCode;
        }

        $result = $this->_signMember($memberCode, $staffId, $storeId, self::SCAN_SIGN_STAFF);
        if (isset($result['msg']) && !empty($result['msg'])) {
            return $result;
        }

        return true;
    }

    /**
     * 扫门店码
     * @param type $storeId
     */
    private function _storeScan($storeId) {
        $memberCode = $this->_registerMember(0, $storeId, self::COME_FROM_STORE);
        if (isset($memberCode['msg']) && !empty($memberCode['msg'])) {
            return $memberCode;
        }
        $result = $this->_signMember($memberCode, 0, $storeId, self::SCAN_SIGN_STAFF);
        if (isset($result['msg']) && !empty($result['msg'])) {
            return $result;
        }

        return true;
    }

    /**
     * 注册会员
     * @param type $staffId
     * @param type $storeId
     * @param type $comeFrom
     * @return boolean
     */
    private function _registerMember($staffId, $storeId, $comeFrom) {

        try {
            $this->_viewMemberIndexModel->startTrans();
            $openIdViewMemberIndex = $this->_viewMemberIndexModel->getViewMemberIndexByCondition([
                'account_code' => $this->_openid
            ]);

            //如果没有找到这个会粉关系，那么就需要注册用户
            if (!$openIdViewMemberIndex) {
                //从jsm.member中获取粉丝信息
                $memberInfo = $this->_membersModel->getMembersByCondition(['openid' => $this->_openid]);
                if (!$memberInfo) {
                    throw new \think\Exception("会粉注册失败，可能原因：会粉" . $this->_openid . "在jsm.member_" . $this->_mpId . "中不存在");
                }

                $memberData = [
                    'come_from' => $comeFrom,
                    'name' => $memberInfo['nickname'],
                    'gender' => $memberInfo['gender'],
                    'birthday' => $memberInfo['birth_day'],
                    'header_img' => $memberInfo['headimgurl'],
                    'account_code' => $this->_openid,
                    'mp_id' => $this->_mpId,
                ];

                //注册账号信息
                $memberIndex = $this->_memberIndexModel->addMemberIndex($memberData, true);
                $memberCode = $memberIndex['member_code'];

                //注册一条账号服务信息
                $memberInfoData = [
                    'first_p' => $staffId,
                    'first_store' => $storeId,
                    'first_qrscene' => $this->_qrscene,
                    'service_p' => $staffId,
                    'service_store' => $storeId,
                    'service_qrscene' => $this->_qrscene
                ];

                $this->_memberIndexInfoModel->addMemberInfo($memberInfoData, $memberCode);

                if ($staffId != 0) {
                    $staffService = new StaffService();
                    $result = $staffService->addCompanyStaffPoint($this->_companyId, 2, $staffId, '拉粉加积分');
                }
            } else {
                //更新当前用户服务信息
                $memberCode = $openIdViewMemberIndex['member_code'];
                $this->_vipId = intval($openIdViewMemberIndex['vip_id']);
                if (!empty($staffId)) {
                    $upinfo['service_p'] = $staffId;
                }
                $upinfo['service_store'] = $storeId;
                $upinfo['service_qrscene'] = $this->_qrscene;
                $upinfo['member_code'] = $memberCode;
                $this->_memberIndexInfoModel->updateIndexInfo($upinfo);
            }

            $this->_viewMemberIndexModel->commit();

            if ($this->_appid == 'wx68f2b24a06465298') {
                $ArvatoMemberService = new ArvatoMemberService();

                if (!$openIdViewMemberIndex) {
                    //宝岛集团需要推送arvato以获取cardno

                    $data = $ArvatoMemberService->newMember($memberIndex['jj_uni_id']);

                    //将cardno更新至index
                    $where['member_code'] = $memberCode;
                    $upinfo['cardno'] = $data['card_no'];
                    $upinfo['card_level'] = $data['card_level'];
                    $this->_memberIndexModel->updateMemberIndex($where, $upinfo);
                } else {

                    $data = $ArvatoMemberService->getCompleteInfo(['jj_uni_id' => $memberIndex['jj_uni_id']]);
                    $data['birthday'] = 0 != (int) $data['birthday'] ? $data['birthday'] : '';

                    $commonPush = new CommonPush();
                    $commonPush->pushToRedis($data, 'updateMember');
                }
            }

            return $memberCode;
        } catch (\think\Exception $ex) {
            return ['msg' => $ex->getMessage()];
        }
    }

    /**
     * 用户扫码签到处理
     * @param type $serviceInfo 
     * @param type $comeFrom Description
     * @param type $companyId Description
     */
    private function _signMember($memberCode, $staffId, $storeId, $comeFrom) {
        //先把非今天的所有服务都结束掉(不管哪个门店，不管是普通还是预约服务)
        $this->_memberSignModel->closeOtherService($memberCode);

        //看看今天有没有签到过
        $where = [
            'member_code' => $memberCode,
            'status' => ['in', "1,2"],
            'add_ts' => ['between', [strtotime(date('Y-m-d 00:00:00')), strtotime(date('Y-m-d 23:59:59'))]],
            'type' => 1//普通服务  
        ];
        $singInfo = $this->_memberSignModel->getMemberSignByCondition($where);
        if ($singInfo) {
            //非同一家门店则关闭签到
            if ($singInfo['service_store'] != $storeId) {
                $this->_memberSignModel->where(['ms_id' => $singInfo['ms_id']])->update(['status' => 3, 'end_time' => time()]);
            }
            //同一家门店不能重复签到
            elseif ($singInfo['status'] == 1 || $singInfo['status'] == 2) {
                return ['msg' => "此会员已经在门店{$storeId}进行服务，不可重复签到;memberCode:{$memberCode}"];
            }
        }
        //签到
        $data = [
            'member_code' => $memberCode,
            'vip_id' => $this->_vipId,
            'come_from' => $comeFrom,
            'service_p' => $staffId,
            'service_store' => $storeId,
            'start_time' => time(),
            'status' => 2,
            'add_ts' => time(),
        ];
        $serviceId = $this->_memberSignModel->addMemberSign($data);
        
        //仅宝岛的才会推送
        if ($this->_appid == 'wx68f2b24a06465298') {
            $memberModel = new ViewMemberIndexModel($this->_companyId);
            $memberInfo = current($memberModel->getViewInfoByCondition(['member_code' =>$memberCode]));
            $commonPush = new CommonPush();
            $storeModel = new StoreModel();
            $shopCode = $storeModel->where(['store_id' => $storeId])->value('trusteeship_id');
            $cardno =  $memberInfo['cardno'];
            $mobile =  $memberInfo['mobile'];
            $data = ['mobile' => $mobile, 'queue_id' => $serviceId, 'openid' => $memberInfo['account_code'], 'card_no' => $cardno, 'shop_code' => $shopCode, 'sign_time' => date('Y/m/d H:i:s'), 'sign_type' => '1', 'res_id' => ''];
            $commonPush->pushToRedis($data, 'memberSignIn');
        }
        
        return true;
    }

    /**
     * 判断会员临码记录表的数据是否正确
     * @param type $memberScanBind
     * @param type $usbId
     * @return boolean
     */
    private function _memberBindScanIsTrue($memberScanBind, $usbId) {

        //$logBussinessExceptionModel = new LogBusinessExceptionModel($this->_companyId);

        if (!$memberScanBind) {
            $data = [
                'action' => 'soa2/index/wechatprocess/_tempScan()',
                'type' => 'nothing',
                'message' => "此扫临码的ID不存：usbId=" . $usbId
            ];

            //$logBussinessExceptionModel->addLog($data);
            return ['msg' => 'temp scan [usbId is error]'];
        }
        if (empty($memberScanBind['member_code'])) {
            $updateData = [
                'status' => 40,
                'message' => '此扫临码绑定的memberCode不存在，不可绑定，usb_id=' . $usbId];
            $this->_memberScanBindModel->updateScanInfo(['usb_id' => $usbId], $updateData);
            return ['msg' => 'temp scan [memberCode is empty]'];
        }

        if ($memberScanBind['status'] == 20) {
            $updateData = ['message' => '重复扫码'];
            $this->_memberScanBindModel->updateScanInfo(['usb_id' => $usbId], $updateData);
            return ['msg' => 'temp scan [status is complete]'];
        }

        if ($memberScanBind['status'] != 10) {
            $updateData = [
                'status' => 40,
                'message' => '此临码记录状态并非是“等待扫码”，不可继续执行，usb_id=' . $usbId];
            $this->_memberScanBindModel->updateScanInfo(['usb_id' => $usbId], $updateData);
            return ['msg' => 'temp scan [status is fail]'];
        }
        return true;
    }

}
